package com.finance.scheduler.job;

import com.finance.base.enums.ComputeStatusEnum;
import com.finance.base.enums.FeeCommitStateEnum;
import com.finance.framework.lang.Page;
import com.finance.framework.qurtz.RedisRunningStatusAcquirer;
import com.finance.logistics.computer.DataExtractor;
import com.finance.framework.qurtz.TaskDescriptor;
import com.finance.logistics.computer.DataExtractorParam;
import com.finance.scheduler.service.AbstractTask;
import com.finance.system.bean.pojo.RecomputeTask;
import com.finance.system.bean.pojo.User;
import com.finance.system.service.IRecomputeTaskService;
import com.finance.util.DateUtil;
import org.apache.commons.collections.CollectionUtils;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.ParseException;
import java.util.*;

/**
 * 重算定时任务
 * Created by CBWL on 2017/5/26.
 */
@Component
public class RecomputeJob implements AbstractTask {
    protected final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private IRecomputeTaskService recomputeTaskService;

    @Autowired
    private DataExtractor dataExtractor;

    @Autowired
    private RedisRunningStatusAcquirer redisRunningStatusAcquirer;

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        List<RecomputeTask> allUndo = this.recomputeTaskService.getAllUnCompute();
        this.logger.info("重算任务调度 未处理任务：{}",String.valueOf(allUndo));
        if(CollectionUtils.isEmpty(allUndo)) {
            return;
        }
        JobDetail jobDetail = context.getJobDetail();
        this.logger.info("context：{}",String.valueOf(context));
        this.logger.info("重算任务详情：{}", String.valueOf(jobDetail));
        List<Page> list = new ArrayList<Page>();
        try{
            for(int i =0 ;i < 5;i++){
                Page page = this.redisRunningStatusAcquirer.acquirePage(context.getTrigger().getKey());
                list.add(page);
            }
            if(CollectionUtils.isEmpty(list)){
                recompute(allUndo,null);//标记
            }else{
                recompute(allUndo, list);
            }
        }catch (Exception e){
            this.logger.error("任务执行异常",e);
        }finally {
            for(Page page : list){
                if(page != null) {
                    this.redisRunningStatusAcquirer.putback(context.getTrigger().getKey(), page);
                }
            }
        }
    }

    private void recompute(List<RecomputeTask> allUndo, List<Page> pages) {
        for (RecomputeTask recomputeTask : allUndo) {
            try {
                checkRecomputeTask(recomputeTask);
                Date signDate = DateUtil.str2date(recomputeTask.getMonth(),DateUtil.YEAR_AND_MONTH_FORMAT);
                if(null == pages){
                    DataExtractorParam dataExtractorParam = new DataExtractorParam.Builder().signDate(signDate).feeCommited(FeeCommitStateEnum.UNCOMMITTED.getState()).recomputeTask(recomputeTask).build();
                    this.dataExtractor.extract2compute(dataExtractorParam);
                }else{
                    for(Page page : pages) {
                        if(page != null){
                            DataExtractorParam dataExtractorParam = new DataExtractorParam.Builder().page(page).signDate(signDate).feeCommited(FeeCommitStateEnum.UNCOMMITTED.getState()).recomputeTask(recomputeTask).build();
                            this.dataExtractor.extract2compute(dataExtractorParam);
                        }
                    }
                }
            } catch (ParseException e) {
                logger.error(e.getMessage(),e);
            }
        }
    }

    private void checkRecomputeTask(RecomputeTask recomputeTask) {
        if(ComputeStatusEnum.UNDO.getState() == recomputeTask.getComputeStatus()){
            recomputeTask.setComputeStatus(ComputeStatusEnum.COMPUTING.getState());
            User user = new User();
            user.setId(0L);
            this.recomputeTaskService.updateRecomputeTask(recomputeTask,user);
        }
    }

    @Override
    public TaskDescriptor descriptor() {
        return new TaskDescriptor("重拉后的再计算","recompute","RecomputeJobtrigger","RecomputeJobtriggerGroup","0 * * * * ?",this.getClass().getCanonicalName(),"处理已经ok的运单数据，计算配费");
    }

}
